using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using UMC.Data;
using System.IO;

namespace UMC.WorkFlow
{
    /// <summary>
    /// 作业实例
    /// </summary>
    public sealed class TaskInstance : IJSONType
    {
        public string Text
        {
            get; set;
        }
        public TaskInstance()
        {
            this.Shapes = new List<Shape>();
            this.Lines = new List<Line>();
            this.Registes = new List<Responder>();
            this.Induces = new List<InduceLine>();
        }
        /// <summary>
        /// 开始加裁日期
        /// </summary>
        public DateTime StartTime { get; set; }
        /// <summary>
        /// 运行状态
        /// </summary>
        public TaskStatus Status { get; set; }
        /// <summary>
        /// 线路集合
        /// </summary>
        [UMC.WorkFlow.Design()]
        public List<Line> Lines
        {
            get;
            private set;
        }
        /// <summary>
        /// 所有节点图形
        /// </summary>
        [UMC.WorkFlow.Design]
        public List<Shape> Shapes
        {
            get;
            private set;
        }
        /// <summary>
        /// 完成时间
        /// </summary>
        public DateTime FinishTime
        {
            get;
            set;
        }
        public ulong ParentId { get; internal set; }
        /// <summary>
        /// 实例唯一性Id
        /// </summary>
        public ulong InstanceId
        {
            get;
            internal set;
        }
        /// <summary>
        /// 作业Id
        /// </summary>
        public ulong TaskId
        {
            get;
            internal set;
        }
        /// <summary>
        /// 申请人身份
        /// </summary>
        public Identity Identity { get; set; }
        /// <summary>
        /// 跳转配置集合
        /// </summary>
        [UMC.WorkFlow.Design()]
        public List<InduceLine> Induces
        {
            get;
            private set;
        }
        /// <summary>
        /// 事件处理集合
        /// </summary>
        [UMC.WorkFlow.Design()]
        public List<Responder> Registes
        {
            get;
            private set;
        }

        public Func<object> GetInstance(string prototypeName)
        {
            switch (prototypeName)
            {
                case "Identity":
                    return () => new UMC.WorkFlow.Identity();
                case "Lines":
                    return () => new Line();
                case "Induces":
                    return () => new InduceLine();
                case "Shapes":
                    return () => new Shape();
                case "Registes":
                    return () => new Responder();
                default:
                    return () => String.Empty;
            }
        }

        public void Read(string key, object value)
        {
            switch (key)
            {
                case "Identity":
                    this.Identity = (Identity)value;
                    break;
                case "Text":
                    this.Text = value as string;
                    break;
                case "ParentId":
                    this.ParentId = Utility.UInt64Parse(value as string) ?? 0;
                    break;
                case "TaskId":
                    this.TaskId = Utility.UInt64Parse(value as string) ?? 0;
                    break;
                case "InstanceId":
                    this.InstanceId = Utility.UInt64Parse(value as string) ?? 0;
                    break;
                case "StartTime":
                    this.StartTime = Utility.TimeSpan(Utility.IntParse(value as string, 0));
                    break;
                case "FinishTime":
                    this.FinishTime = Utility.TimeSpan(Utility.IntParse(value as string, 0));
                    break;
                case "Status":
                    this.Status = Utility.Parse(value as string, TaskStatus.None);
                    break;
                case "Lines":
                    Array array = value as Array;
                    if (array != null)
                    {
                        foreach (var v in array)
                        {
                            this.Lines.Add((Line)v);
                        }
                    }
                    break;
                case "Induces":
                    Array induces = value as Array;
                    if (induces != null)
                    {
                        foreach (var v in induces)
                        {
                            this.Induces.Add((InduceLine)v);
                        }
                    }
                    break;
                case "Shapes":
                    Array shapes = value as Array;
                    if (shapes != null)
                    {
                        foreach (var v in shapes)
                        {
                            this.Shapes.Add((Shape)v);
                        }
                    }
                    break;
                case "Registes":
                    Array registes = value as Array;
                    if (registes != null)
                    {
                        foreach (var v in registes)
                        {
                            this.Registes.Add((Responder)v);
                        }
                    }
                    break;



            }
        }


        void WriteProperty(TextWriter writer)
        {
            if (String.IsNullOrEmpty(this.Text) == false)
            {
                writer.Write(',');
                JSON.Serialize("Text", this.Text, writer);
            }
            var time = Utility.TimeSpan(this.FinishTime);
            if (time > 0)
            {
                writer.Write(',');
                JSON.Serialize("FinishTime", time, writer);
            }
            time = Utility.TimeSpan(this.StartTime);
            if (time > 0)
            {
                writer.Write(',');
                JSON.Serialize("StartTime", time, writer);
            }
            if (this.Identity != null)
            {
                writer.Write(',');
                JSON.Serialize("Identity", this.Identity, writer);
            }

            if (this.ParentId > 0)
            {
                writer.Write(',');
                JSON.Serialize("ParentId", this.ParentId, writer);
            }

            if (this.InstanceId > 0)
            {
                writer.Write(',');
                JSON.Serialize("InstanceId", this.InstanceId, writer);
            }

            if (this.TaskId > 0)
            {
                writer.Write(',');
                JSON.Serialize("TaskId", this.TaskId, writer);
            }

            if (this.Status > TaskStatus.None)
            {
                writer.Write(',');
                JSON.Serialize("Status", this.Status, writer);
            }

            writer.Write(',');
            JSON.Serialize("Lines", this.Lines, writer);
            writer.Write(',');
            JSON.Serialize("Shapes", this.Shapes, writer);
            writer.Write(',');
            JSON.Serialize("Induces", this.Induces, writer);
            writer.Write(',');
            JSON.Serialize("Registes", this.Registes, writer);
        }

        public void Write(TextWriter writer)
        {
            writer.Write('{');
            JSON.Serialize(JSON.Constructor, this.GetType().Name, writer);

            WriteProperty(writer);
            writer.Write('}');
        }
    }
}
